package com.t.bricks.bussiness.service.orders.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.t.bricks.bussiness.db.dao.common.CommonDao;
import com.t.bricks.bussiness.db.dao.orders.OrdersDao;
import com.t.bricks.bussiness.db.entity.orders.Orders;
import com.t.bricks.bussiness.db.entity.orders.WaresInfo;
import com.t.bricks.bussiness.db.entity.orders.base.CustomerAccountBase;
import com.t.bricks.bussiness.db.entity.orders.base.OrdersDetailBase;
import com.t.bricks.bussiness.service.orders.OrdersService;
import com.t.bricks.bussiness.util.orders.DelveryUtil;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.utils.function.data.IntegerUtil;
import com.t.bricks.utils.function.data.MoneyUtil;
import com.t.bricks.utils.function.data.StringUtil;
import com.t.bricks.utils.function.date.TimeUtil;
import com.t.bricks.utils.function.encode.MD5Util;
import com.t.bricks.utils.spring.ModuleUtil;

/**
 * 订单'Orders表'基本业务操作类接口实现
 * @author HuangXinBian
 * @DateTime 2022年06月22日 15:25:29
 */
@Service
public class OrdersServiceImpl implements OrdersService<Orders> {

	@Autowired
	private OrdersDao<Orders> ordersDao;
	
	@Autowired
	private CommonDao commonDao;

	@Value("${app.kuaidi.api.id:配置文件中的快递鸟配置app.kuaidi.api.id未设置}")
	private String kdApiId;

	@Value("${app.kuaidi.api.key:配置文件中的快递鸟配置app.kuaidi.api.key未设置}")
	private String kdApiKey;

	@Value("${app.kuaidi.api.request.type:1002}")
	private Integer kdApiType;
	
	/**
	 * 创建sRecordKey用的干扰串
	 */
	@Value("${app.record.key.jam:123456}")
	private String recordKeyJam;
	
	/**
	 * md5加密干扰串
	 * 注意,必须与BaseSystem中的干扰串一样,否则无法登录
	 */
	@Value("${app.md5.key:未设置app.md5.key配置项}")
	private String appMd5Key;
	
	//流水号
	private static int iNumber = 0;

	/**
	 * 添加
	 * @Param orders
	 * @return int
	 */
	@Override
	public MsgEmity addCustom(Orders orders) {
		//MsgEmity me = validAdd(orders);
		if (null == orders) {
			return MsgEmity.err(8001, "订单数据为空");
		}
		
		orders.setsSequence("随便");
		orders.setsRechargeNo(null);//充值订单号不能在此传入
		
		MsgEmity me = ModuleUtil.validDbEntityByAdd(orders);// 通用的基本数据验证,如果要进行比较复杂的数据验证则可以屏蔽掉此方法自行编写
		if (!me.isSuccess()) {
			return me;
		}
		
		if (!MoneyUtil.isPlus(orders.getmMoney())) {
			return MsgEmity.err(8002, "总金额必须是正数");
		}
		
		if (MoneyUtil.isNegative(orders.getmMoneyPay())) {
			return MsgEmity.err(8003, "支付金额不能是负数");
		}
	
		if (MoneyUtil.isNegative(orders.getmCouponPay())) {
			return MsgEmity.err(8004, "支付优惠卷不能是负数");
		}
		
		if (null == orders.getiTallyPay() || orders.getiTallyPay() < 0) {
			return MsgEmity.err(8005, "支付积分不能是负数");
		}
		
		if (null == orders.getiTallyLargess() || orders.getiTallyLargess() < 0) {
			return MsgEmity.err(8006, "赠送积分不能是负数");
		}
		
		if (null == orders.getiTallyLargess() || orders.getiTallyLargess() != 0) {
			return MsgEmity.err(8007, "当前版本不允许通过下单赠送积分");
		}
		
		if (!"/0/1/2/3/4/5/6/".contains(String.valueOf(orders.getiPay()))) {
			return MsgEmity.err(8008, "付款方式限定[0:其它;1:现金;2:支付宝;3微信;4:银行转账;5:赊账:6馈赠]");
		}

		String sAddress = orders.getsCustomerAddress();
		if (null == sAddress || "".equals(sAddress.trim())) {
			return MsgEmity.err(8009, "收货地址不能为空");
		}
		
		BigDecimal payMoney = MoneyUtil.sum(orders.getmMoneyPay(),
				orders.getmCouponPay(),
				MoneyUtil.formCent(orders.getiTallyPay()),//分转元
				orders.getmFreight());
		if (payMoney.compareTo(orders.getmMoney()) != 0) {
			return MsgEmity.err(8010, "总金额与支付的金额累加不符合");
		}
		
		int iSize = orders.getDetails().size();
		if (iSize < 1) {
			return MsgEmity.err(8020, "商品数据详情为空");
		}
		
		if (iSize > 50) {
			return MsgEmity.err(8021, "商品数据详情数量限定50个");
		}
		
		me = ordersDao.reckonFreight(orders.getDetails(), sAddress.split(";")[0]);
		if (!me.isSuccess()) {
			return me;
		}
		
		BigDecimal mFreight = me.getData();
		if (mFreight.compareTo(orders.getmFreight()) != 0) {
			return MsgEmity.err(8022, "提供的运费信息不符合");
		}

		me = ModuleUtil.supplyDbEntityAttrByAdd(orders);// 补充数据,如添加id、当前用户、当前时间等
		if (!me.isSuccess()) {
			return me;
		}
		
		String sCustomerId = orders.getsCreator();
		if (!sCustomerId.equals(orders.getsCustomerId())) {
			return MsgEmity.err(8023, "顾客账号与当前账户不符");
		}
		
		String sOrderId = orders.getsId();
		List<String> sIds = new ArrayList<>(iSize);//商品编号集合
		BigDecimal sumMoney = BigDecimal.ZERO;//总金额
		
		for (int i = 0; i < orders.getDetails().size(); i++) {
			OrdersDetailBase detail = orders.getDetails().get(i);
			if (detail.getiNumber() < 1) {
				return MsgEmity.err(8024, "商品详情", detail.getsWaresName(), "的数量必须大于0");
			}
			
			if (!MoneyUtil.isPlus(detail.getmPrice())) {
				return MsgEmity.err(8025, "商品单价必须是正数");
			}
			
			if (MoneyUtil.isNegative(detail.getmCouponPay())) {
				return MsgEmity.err(8026, "支付优惠卷不能是负数");
			}
			
			if (null != detail.getiTallyLargess() && detail.getiTallyLargess() != 0) {
				return MsgEmity.err(8027, "当前版本不允许单独对商品赠送积分");
			}
			
			if (null == detail.getsWaresId() || "".equals(detail.getsWaresId())) {
				return MsgEmity.err(8028, "商品编号不能为空");
			}
			
			if (null == detail.getsCartId() || "".equals(detail.getsCartId())) {
				return MsgEmity.err(8029, "购物车编号不能为空");
			}
			
			detail.setsOrderId(sOrderId);
			detail.setsId(String.format("%s_%02d", sOrderId, (i +1)));
			
			sIds.add(detail.getsWaresId());
			sumMoney = MoneyUtil.addMoney(sumMoney, MoneyUtil.mul(detail.getmPrice(), detail.getiNumber()));
		}
		
		if (MoneyUtil.sum(orders.getmFreight(), sumMoney).compareTo(orders.getmMoney()) != 0) {
			return MsgEmity.err(8029, "总金额与商品累计金额不符合");
		}

		me = this.callMapping("findWaresInfo", sIds);
		if (!me.isSuccess()) {
			return MsgEmity.err(8101, "商品信息查询失败");
		}
		
		List<WaresInfo> waresList = me.getData();
		if (waresList.size() != iSize) {
			return MsgEmity.err(8102, "商品数量与详情未能对应");
		}

		Date now = new Date();
		for (WaresInfo wares : waresList) {
			if (wares.getdStart().after(now)) {
				return MsgEmity.err(8102, "商品尚未上架,不要搞事");
			}

			if (wares.getdStop().before(now)) {
				return MsgEmity.err(8103, "商品已经下架,不要搞事");
			}
			
			for (OrdersDetailBase detail : orders.getDetails()) {
				if (!wares.getsId().equals(detail.getsWaresId())) {
					continue;
				}
				
				if (null == detail.getmPrice()) {
					detail.setmPrice(BigDecimal.ZERO);
				}
				
				if (null == detail.getiTallyLargess()) {
					detail.setiTallyLargess(0);
				}
				
				if (null == detail.getiNumber()) {
					detail.setiNumber(1);
				}
				
				if (wares.getmCurrentPrice().compareTo(detail.getmPrice()) != 0) {
					return MsgEmity.err(8104, "商品价格不符合,商品名:", wares.getsName());
				}
				
				if (wares.getiTallyLargess().intValue() != detail.getiTallyLargess().intValue()) {
					return MsgEmity.err(8105, "商品赠送积分不符合,商品名:", wares.getsName());
				}
				
				if (wares.getiCount().intValue() < detail.getiNumber().intValue()) {
					return MsgEmity.err(8106, "商品库存不足,商品名:", wares.getsName());
				}
				
				if (wares.getiMinBuy().intValue() > detail.getiNumber().intValue()) {
					return MsgEmity.err(8107, "小于最小购买量,商品名:", wares.getsName());
				}
				
				if (wares.getiMaxBuy().intValue() < detail.getiNumber().intValue()) {
					return MsgEmity.err(8108, "超出最大购买量,商品名:", wares.getsName());
				}
				
				detail.setsWaresName(wares.getsName());
			}
		}

		synchronized (OrdersServiceImpl.class) {
			iNumber = iNumber + 1;
			if (iNumber > 9999) {
				iNumber = 1;
			}
			
			orders.setsSequence(String.format("%s-%04d", TimeUtil.serial(), iNumber));
		}
		
		return ordersDao.addCustom(orders);
	}
	
	/**
	 * 查询购物车对应详情
	 * @param cartIds 购物车编号(分号分隔)
	 * @return List<OrdersDetailBase>
	 */
	@Override
	public MsgEmity cartToDetail(String cartIds) {
		if (null == cartIds || "".equals(cartIds.trim())) {
			return MsgEmity.err(8001, "购物车编号参数为空");
		}

		String[] array = cartIds.split(";");
		List<String> list = new ArrayList<>(array.length);
		for (String string : array) {
			if (null == string || "".equals(string.trim())) {
				continue;
			}
			
			list.add(string.trim());
		}
		
		if (list.size() < 1) {
			return MsgEmity.err(8002, "购物车编号内容为空");
		}
		
		return ordersDao.cartToDetail(list, ModuleUtil.currentLoginUserId());
	}
	
	/**
	 * 设置状态-支付
	 * @param sId 记录编号
	 * @param sRechargeNo 充值订单号
	 * @param iVersion 记录版本号
	 * @param sPayPass 支付密码
	 * @param sPaySignPass 支付手势密码
	 * @return
	 */
	@Override
	public MsgEmity pay(String sId, String sRechargeNo, Integer iVersion, String sPayPass, String sPaySignPass) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}
		
		if (null == sRechargeNo || "".equals(sRechargeNo.trim()) || sRechargeNo.length() > 64) {
			return new MsgEmity(false, "充值订单号内容为空", 8014);
		}
		
		MsgEmity me = ordersDao.isAstrictBuy(sId, ModuleUtil.currentLoginUserId());//订单中是否包含已经购买过的限购商品
		if (!me.isSuccess()) {
			return me.appendDataCode(20);
		}
		
		if (0 < ((Integer)me.getData()).intValue()) {
			return new MsgEmity(false, "订单中包含已购买的限购商品", 8015);
		}
		
		if ((null == sPayPass || "".equals(sPayPass.trim()))
				&& ((null == sPaySignPass || "".equals(sPaySignPass.trim())))) {
			return new MsgEmity(false, "支付密码或支付手势密码参数必须提供一个！", 8003);
		}

		me = this.callMapping("findAccountByOrder", sId);
		if (!me.isSuccess()) {
			return me.appendDataCode(10);
		}
		
		CustomerAccountBase customerAccount = me.getData();
		if (null == customerAccount) {
			return new MsgEmity(false, "没有找到对应的顾客账户信息！", 8004);
		}
		
		if (null != sPayPass && !"".equals(sPayPass.trim())) {
			String temp = MD5Util.md5(sPayPass, appMd5Key);
			if (!temp.equals(customerAccount.getsPayPass()) ) {
				return new MsgEmity(false, "支付密码错误！", 8005);
			}
		}
		
		if (null != sPaySignPass && !"".equals(sPaySignPass.trim())) {
			String temp = MD5Util.md5(sPaySignPass, appMd5Key);
			if (!temp.equals(customerAccount.getsPaySignPass()) ) {
				return new MsgEmity(false, "支付手势密码错误！", 8006);
			}
		}
		
		String temp = customerAccount.createRecordKey(recordKeyJam);
		if (!temp.equals(customerAccount.getsRecordKey())) {
			return new MsgEmity(false, "账户记录验证密钥不一致！", 8007);
		}

		me = this.findById(sId, true);
		if (!me.isSuccess()) {
			return me.appendDataCode(10);
		}
		
		Orders orders = me.getData();
		if (orders.getiState().intValue() != 1) {
			return MsgEmity.err(8008, "订单不是'待支付'状态！当前状态:", orders.getiState().toString());
		}

		if (!orders.getsCustomerId().equals(customerAccount.getsId())) {
			return new MsgEmity(false, "订单不属于当前用户！", 8009);
		}
		
		if (orders.getmMoneyPay().compareTo(customerAccount.getmFund()) > 1) {//1 则a > b
			return new MsgEmity(false, "账户余额不足以支付订单支付金额！", 8010);
		}
		
		BigDecimal mPAndF = MoneyUtil.sum(orders.getmMoneyPay(), orders.getmFreight());//运费与支付金额合计
		if (mPAndF.compareTo(customerAccount.getmFund()) > 1) {//1 则a > b
			return new MsgEmity(false, "账户余额不足以支付订单支付金额与运费！", 8011);
		}
		
		if (orders.getiTallyPay().intValue() > customerAccount.getiTally().intValue()) {
			return new MsgEmity(false, "账户积分不足以支付订单积分！", 8012);
		}
		
		if (!iVersion.equals(orders.getiVersion())) {
			return MsgEmity.err(8013, "订单版本号与提供的参数不符,可能数据已经被改变");
		}
		
		return ordersDao.pay(sId, sRechargeNo, iVersion);
	}

	/**
	 * 设置状态-免密支付(仅限订单所属顾客操作)
	 * @param sId 记录编号
	 * @param sRechargeNo 充值订单号
	 * @param iVersion 记录版本号
	 * @return
	 */
	@Override
	public MsgEmity payNotPass(String sId, String sRechargeNo, Integer iVersion) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}
		
		if (null == sRechargeNo || "".equals(sRechargeNo.trim()) || sRechargeNo.length() > 64) {
			return new MsgEmity(false, "充值订单号内容为空", 8014);
		}

		String userId = ModuleUtil.currentLoginUserId();
		
		MsgEmity me = ordersDao.isAstrictBuy(sId, userId);//订单中是否包含已经购买过的限购商品
		if (!me.isSuccess()) {
			return me.appendDataCode(20);
		}
		
		if (0 < ((Integer)me.getData()).intValue()) {
			return new MsgEmity(false, "订单中包含已购买的限购商品", 8015);
		}
		
		me = this.callMapping("findAccountByOrder", sId);//根据订单取对应顾客账户
		if (!me.isSuccess()) {
			return me.appendDataCode(10);
		}
		
		CustomerAccountBase customerAccount = me.getData();
		if (null == customerAccount) {
			return new MsgEmity(false, "没有找到对应的顾客账户信息！", 8004);
		}
		
		if (null == userId || "".equals(userId.trim())) {
			return new MsgEmity(false, "无法识别的账户信息,请检查登录！", 8005);
		}
		
		if (!customerAccount.getsId().equals(userId)) {
			return new MsgEmity(false, "非订单所属顾客不能操作此接口！", 8006);
		}
		
		String temp = customerAccount.createRecordKey(recordKeyJam);
		if (!temp.equals(customerAccount.getsRecordKey())) {
			return new MsgEmity(false, "账户记录验证密钥不一致！", 8007);
		}

		me = this.findById(sId, true);
		if (!me.isSuccess()) {
			return me.appendDataCode(20);
		}
		
		Orders orders = me.getData();
		if (orders.getiState().intValue() != 1) {
			return MsgEmity.err(8007, "订单不是'待支付'状态！当前状态:", orders.getiState().toString());
		}

		if (!orders.getsCustomerId().equals(userId)) {
			return new MsgEmity(false, "订单不属于当前用户！", 8008);
		}
		
		if (orders.getmMoneyPay().compareTo(customerAccount.getmFund()) > 1) {//1 则a > b
			return MsgEmity.err(8009, "账户余额不足以支付订单支付金额！当前订单待支付金额:", orders.getmMoneyPay().toString(), ",账户余额:", customerAccount.getmFund().toString());
		}
		
		BigDecimal mPAndF = MoneyUtil.sum(orders.getmMoneyPay(), orders.getmFreight());//运费与支付金额合计
		if (mPAndF.compareTo(customerAccount.getmFund()) > 1) {//1 则a > b
			return new MsgEmity(false, "账户余额不足以支付订单支付金额与运费！", 8010);
		}
		
		if (orders.getiTallyPay().intValue() > customerAccount.getiTally().intValue()) {
			return MsgEmity.err(8011, "账户积分不足以支付订单积分！当前订单待支付积分:", orders.getiTallyPay().toString(), ",账户积分:", customerAccount.getiTally().toString());
		}
		
		if (!iVersion.equals(orders.getiVersion())) {
			return MsgEmity.err(8012, "订单版本号与提供的参数不符,可能数据已经被改变");
		}
		
		return ordersDao.pay(sId, sRechargeNo, iVersion);
	}
	
	/**
	 * 设置状态-销售
	 * @param sId
	 * @param iVersion
	 * @param sSalesmanId
	 * @param sSalesman
	 * @return
	 */
	@Override
	public MsgEmity sales(String sId, Integer iVersion) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}

		List<String> fieldNames = Arrays.asList("sCustomerId", "iState", "iVersion");
		MsgEmity me = this.getValueByFieldName(sId, fieldNames, false);
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders orders = me.getData();
		if (orders.getiState() != 2) {
			return new MsgEmity(false, "当前状态必须是支付状态！", 8003);
		}
		
		String sSalesmanId = ModuleUtil.currentLoginUserId();
		String sSalesman = ModuleUtil.currentLoginUserName();
		
		return ordersDao.sales(sId, iVersion, sSalesmanId, sSalesman);
	}
	
	/**
	 * 设置状态-送出(待揽货)
	 * @param sId
	 * @param iVersion
	 * @param sDeliveryDate 送出时间
	 * @param sDelivery
	 * @param sDeliveryman
	 * @param sDeliveryNo
	 * @param sDelveryCode
	 * @return
	 */
	@Override
	public MsgEmity delivery(String sId, Integer iVersion, String sDeliveryDate,
			String sDelivery, String sDeliveryman, String sDeliveryNo,
			String sDelveryCode) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}
		
		Date dDelivery = TimeUtil.toDate(sDeliveryDate);
		if (null == dDelivery) {
			return MsgEmity.err(8003, "送出时间格式错误");
		}
		
		sDelivery = StringUtil.trim(sDelivery);
		if (StringUtil.len(sDelivery) > 200) {
			return MsgEmity.err(8004, "出库说明超出长度(200)");
		}
		
		sDeliveryman = StringUtil.trim(sDeliveryman);
		if (null == sDeliveryman) {
			return MsgEmity.err(8005, "送货人不能为空");
		}
		
		if (StringUtil.len(sDeliveryman) > 32) {
			return MsgEmity.err(8006, "送货人长度超出");
		}
		
		sDeliveryNo = StringUtil.trim(sDeliveryNo);
		if (StringUtil.len(sDeliveryNo) > 32) {
			return MsgEmity.err(8007, "快递编号长度超出");
		}
		
		sDelveryCode = StringUtil.trim(sDelveryCode);
		if (StringUtil.len(sDelveryCode) > 32) {
			return MsgEmity.err(8007, "快递公司编码长度超出");
		}

		List<String> fieldNames = Arrays.asList("sCustomerId", "iState", "iVersion");
		MsgEmity me = this.getValueByFieldName(sId, fieldNames, false);
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders orders = me.getData();
		if (orders.getiState() != 3) {
			return new MsgEmity(false, "当前状态必须是出库状态！", 8003);
		}
		
		return ordersDao.delivery(sId, iVersion, dDelivery, sDelivery,
				sDeliveryman, sDeliveryNo, sDelveryCode);
	}
	
	/**
	 * 顾客签收
	 * @param sId
	 * @param iVersion
	 * @param sSignIn
	 * @return
	 */
	@Override
	public MsgEmity signIn(String sId, Integer iVersion, String sSignIn) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}

		List<String> fieldNames = Arrays.asList("sCustomerId", "iState", "iVersion");
		MsgEmity me = this.getValueByFieldName(sId, fieldNames, false);
		if (!me.isSuccess()) {
			return me;
		}

		Orders orders = me.getData();
		int iState = orders.getiState();
		if (iState < 3) {
			return new MsgEmity(false, "尚未出库，不能签收！", 8003);
		}
		
		if (iState == 5) {
			return new MsgEmity(true, "已经签收过！", 8999);
		}
		
		if (iState == 6) {
			return new MsgEmity(true, "已经确认,不用签收！", 8999);
		}
		
		if (iState > 6) {
			return new MsgEmity(false, "已经不允许签收操作！", 8004);
		}
		
		String sUserId = ModuleUtil.currentLoginUserId();
		if (!sUserId.equals(orders.getsCustomerId())) {
			return new MsgEmity(false, "只有顾客才能操作！", 8005);
		}
		
		return ordersDao.signIn(sId, iVersion, sSignIn.trim());
	}
	
	/**
	 * 顾客确认
	 * @param sId
	 * @param iVersion
	 * @param sConfirm
	 * @return
	 */
	@Override
	public MsgEmity confirm(String sId, Integer iVersion, String sConfirm) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}

		List<String> fieldNames = Arrays.asList("sCustomerId", "iState", "iVersion");
		MsgEmity me = this.getValueByFieldName(sId, fieldNames, false);
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders orders = me.getData();
		int iState = orders.getiState();
		if (iState < 3) {
			return new MsgEmity(false, "尚未出库，不能'确认'！", 8003);
		}
		
		if (iState == 6) {
			return new MsgEmity(true, "已经确认,不用再次'确认'！", 8999);
		}
		
		if (iState > 6) {
			return new MsgEmity(false, "已经不允许'确认'操作！", 8004);
		}
		
		String sUserId = ModuleUtil.currentLoginUserId();
		if (!sUserId.equals(orders.getsCustomerId())) {
			return new MsgEmity(false, "只有顾客才能操作！", 8005);
		}
		
		return ordersDao.confirm(sId, iVersion, sConfirm);
	}
	
	/**
	 * 顾客退货申请
	 * @param sId
	 * @param iVersion
	 * @param sReturnApply 退货申请说明
	 * @return
	 */
	@Override
	public MsgEmity returnApply(String sId, Integer iVersion, String sReturnApply) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}

		List<String> fieldNames = Arrays.asList("sCustomerId", "iState", "iVersion");
		MsgEmity me = this.getValueByFieldName(sId, fieldNames, false);
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders orders = me.getData();
		int iState = orders.getiState();
		if (iState < 2) {
			return new MsgEmity(false, "尚未支付，不能退货！", 8003);
		}
		
		if (iState == 6) {
			return new MsgEmity(false, "已经确认,不能退货！", 8999);
		}
		
		if (iState > 7) {
			return new MsgEmity(true, "已经不允许退货操作！", 8004);
		}
		
		String sUserId = ModuleUtil.currentLoginUserId();
		if (!sUserId.equals(orders.getsCustomerId())) {
			return new MsgEmity(false, "只有顾客才能操作！", 8005);
		}
		
		return ordersDao.returnApply(sId, iVersion, sReturnApply);
	}
	
	/**
	 * 退货审核
	 * 8:退货审核不通过;9:退货申请通过;10:已退款
	 * @param sId
	 * @param iVersion
	 * @param iState
	 * @return
	 */
	@Override
	public MsgEmity untreadAudit(String sId, Integer iVersion, Integer iState) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}

		List<String> fieldNames = Arrays.asList("sCustomerId", "iState", "iVersion");
		MsgEmity me = this.getValueByFieldName(sId, fieldNames, false);
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders orders = me.getData();
		if (orders.getiState() < 20) {
			return new MsgEmity(false, "必须先审计！", 8003);
		}
		
		String sAuditId = ModuleUtil.currentLoginUserId();
		if (!sAuditId.equals(orders.getsCustomerId())) {
			return new MsgEmity(false, "信息版本不一致,记录可能已经修改！", 8004);
		}
		
		return ordersDao.untreadAudit(sId, iVersion, iState);
	}
	
	/**
	 * 设置状态-审核
	 * @param sId
	 * @param iVersion
	 * @param sAuditId
	 * @param sAudit
	 * @return
	 */
	@Override
	public MsgEmity audit(String sId, Integer iVersion) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}

		List<String> fieldNames = Arrays.asList("sCustomerId", "iState", "iVersion");
		MsgEmity me = this.getValueByFieldName(sId, fieldNames, false);
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders orders = me.getData();
		if (orders.getiState() > 20) {
			return new MsgEmity(false, "不允许重复审计！", 8003);
		}
		
		String sAuditId = ModuleUtil.currentLoginUserId();
		String sAudit = ModuleUtil.currentLoginUserName();
		
		return ordersDao.audit(sId, iVersion, sAuditId, sAudit);
	}
	
	/**
	 * 设置状态-复审
	 * @param sId
	 * @param iVersion
	 * @param sRecheckId
	 * @param sRecheck
	 * @return
	 */
	@Override
	public MsgEmity recheck(String sId, Integer iVersion) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}

		List<String> fieldNames = Arrays.asList("iState", "iVersion");
		MsgEmity me = this.getValueByFieldName(sId, fieldNames, false);
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders orders = me.getData();
		if (orders.getiState() < 20) {
			return new MsgEmity(false, "必须先审计！", 8003);
		}
		
		String sRecheckId = ModuleUtil.currentLoginUserId();
		String sRecheck = ModuleUtil.currentLoginUserName();
		
		return ordersDao.recheck(sId, iVersion, sRecheckId, sRecheck);
	}
	
	/**
	 * 根据订单详情和目的地,测算运费
	 * @param iNumbers 订单详情中的数量集合(分号分隔)
	 * @param sWaresIds 订单详情中的商品编号集合(分号分隔)
	 * @param sArea 目的地
	 * @return
	 */
	@Override
	public MsgEmity reckonFreight(String iNumbers, String sWaresIds, String sArea) {
		if (null == iNumbers || "".equals(iNumbers.trim())) {
			return new MsgEmity(false, "数量集合为空！", 8001);
		}
		
		if (null == sWaresIds || "".equals(sWaresIds.trim())) {
			return new MsgEmity(false, "商品编号集合为空！", 8002);
		}
		
		if (null == sArea || "".equals(sArea.trim())) {
			return new MsgEmity(false, "目的地为空", 8003);
		}
		
		String[] numbers = iNumbers.split(";");
		String[] waresIds = sWaresIds.split(";");
		if (numbers.length != waresIds.length) {
			return new MsgEmity(false, "数量集合与商品编号集合没有对应！", 8002);
		}

		List<OrdersDetailBase> details = new ArrayList<>(numbers.length);
		for (int i = 0; i < numbers.length; i++) {
			OrdersDetailBase detail = new OrdersDetailBase();
			detail.setiNumber(IntegerUtil.strToInt(numbers[i], 99999));
			detail.setsWaresId(waresIds[i]);
			
			details.add(detail);
		}
		
		return ordersDao.reckonFreight(details, sArea.trim());
	}
	
	/**
	 * 取订单创建时间
	 * @param sId 订单详编号
	 * @return
	 */
	@Override
	public MsgEmity getCreateDate(String sId) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "订单详编号为空！", 8001);
		}
		
		return this.getValueByFieldName(sId, "dCreateDate,sCustomerId,iState", false);
	}
	
	/**
	 * 查看快递信息
	 * @param sId
	 * @return
	 */
	@Override
	public MsgEmity lookDelivery(String sId) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "订单详编号为空！", 8001);
		}

		List<String> fieldNames = Arrays.asList("sDeliveryNo", "sDelveryCode",
				"dPay", "dDelivery", "iState", "sCustomerPhone");
		MsgEmity me = this.getValueByFieldName(sId, fieldNames, false);//过滤非创建者数据
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders orders = me.getData();
		if (orders.getiState() < 4) {
			return new MsgEmity(false, "尚未出货！", 8002);
		}
		
		me = DelveryUtil.orderOnlineByJson(kdApiId, kdApiKey, kdApiType,
				orders.getsDelveryCode(), orders.getsDeliveryNo(), orders.getsCustomerPhone());
		
		if (!me.isSuccess()) {
			return me;
		}
		
		return me.setMsg(String.format("%s;%s", TimeUtil.toStr(orders.getdPay()),
				TimeUtil.toStr(orders.getdDelivery())));
	}

	//---------------------------- 订单支付时间过期处理 开始 ---------------------//

	//放到数据库处理,否则控制台都是日志输出
	/**
	 * 订单支付时间过期间隔,建议使用数据库存储过程
	 * 关闭:99999;默认:99999
	 */
	@Value("${app.order.pay.timeout:99999}")
	private Integer iMinute;
	
	private static boolean isBus = false;
	
	/**
	 * 订单支付时间过期处理
	 * Spring 启动完成后，会自动调用此方法
	 */
	@PostConstruct
	private void doThread() {
		if (99999 == iMinute.intValue()) {
			return;
		}
		
		new Thread(() -> {
			while(true) {
				try {
					if (isBus) {
						Thread.sleep(1000);
						continue;
					}
					
					isBus = true;
					this.callMapping("timeOut", iMinute);//直接调用Mapping操作
					Thread.sleep(1000);
					isBus = false;
				} catch (Exception e) {
					isBus = false;
				}
			}
		}).start();
	}
	
	//---------------------------- 订单支付时间过期处理 开始 ---------------------//
	
}
